
#include "tp_typedef.h"
#include "tp_wnd_manager.h"
#include "tp_source_primary.h"
#include "tp_memory.h"
#include "tp_log.h"

typedef struct _PrivInfo
{
	int wnd_nr;
	TpWidget* windows[TP_MAX_WINDOWS];
}PrivInfo;


/* 添加一个新创建的窗口，需要更新显示 */
static TpRet tp_wnd_manager_default_add(TpWndManager* thiz, TpWidget* wnd)
{
	DECL_PRIV(thiz, priv);

	if (NULL == thiz || NULL == wnd || NULL == priv)
	{
		return TP_RET_BADARGS;
	}

	if(priv->wnd_nr >= TP_MAX_WINDOWS)
	{
		tp_widget_destroy(wnd);

		tp_loge("tp_wnd_manager_default_add: too many app windows.");

        return TP_RET_FAIL;
	}

	priv->windows[priv->wnd_nr] = wnd;
	priv->wnd_nr++;

	return TP_RET_OK;
}

static TpRet tp_wnd_manager_default_remove(TpWndManager* thiz, TpWidget* wnd)
{
	int i, j;
	DECL_PRIV(thiz, priv);

	if (NULL == thiz || NULL == priv)
	{
		tp_widget_destroy(wnd);

		return TP_RET_BADARGS;
	}

	for (i = 0; i < priv->wnd_nr; ++i)
	{
		if(priv->windows[i] == wnd)
		{
			for (j = i; j < priv->wnd_nr; ++j)
			{
				priv->windows[j] = priv->windows[j+1];
			}
			priv->wnd_nr--;

			tp_widget_destroy(wnd);

			break;
		}
	}

	return TP_RET_OK;
}

static TpRet tp_wnd_manager_default_on_event(TpWndManager* thiz, TpEvent* event)
{
	TpWidget* wnd = NULL;
	DECL_PRIV(thiz, priv);

	/* 可在此处加入hook，此项功能留待以后实现。*/

	switch (event->type)
	{
		/*
		 * 鼠标消息和键盘消息交给当前窗口（顶层窗口）处理。
		 * 若是鼠标单击再由当前窗口分发到具体的控件。
		 */
		case TP_EVENT_LBUTTON_DOWN:
		case TP_EVENT_LBUTTON_UP:
		case TP_EVENT_MOUSE_MOVE:
		{
			/* tp_logi("mouse: x=%d, y=%d.", event->u_event.mouse.x, event->u_event.mouse.y); */

			wnd = priv->windows[priv->wnd_nr-1];
			return tp_widget_on_event(wnd, event);
		}
		case TP_EVENT_KEY_DOWN:
		case TP_EVENT_KEY_UP:
		{
			/* tp_logi("key: code=%d.", event->u_event.key.code); */

			wnd = priv->windows[priv->wnd_nr-1];
			return tp_widget_on_event(wnd, event);
		}
		/* widget的显示隐藏由具体的widget对象来实现。 */
		case TP_EVENT_WIDGET_SHOW:
		{
			return tp_widget_on_event(event->u_event.widget.widget, event);
		}
		case TP_EVENT_NOP: break;
		default: break;
	}

	return TP_RET_OK;
}

static void tp_wnd_manager_default_destroy(TpWndManager* thiz)
{
	if (NULL != thiz)
	{
		tp_free(thiz);
	}

	return;
}

TpWndManager* tp_wnd_manager_default_create(int wnd_nr)
{
    int i;
	TpWndManager* thiz = NULL;

	thiz = (TpWndManager*)tp_alloc(sizeof(TpWndManager) + sizeof(PrivInfo));
	if(NULL != thiz)
	{
		DECL_PRIV(thiz, priv);

		thiz->add = tp_wnd_manager_default_add;
		thiz->remove = tp_wnd_manager_default_remove;
		thiz->on_event = tp_wnd_manager_default_on_event;
		thiz->destroy = tp_wnd_manager_default_destroy;

        for(i = 0; i < TP_MAX_WINDOWS; ++i)
        {
            priv->windows[i] = NULL;
        }
        priv->wnd_nr = 0;
	}

	return thiz;
}
